﻿using System.Diagnostics;
using System.Dynamic;

namespace Wargame_V3_1
{
    class Interact : DynamicObject
    {
        // 记录interact各属性的类型，在InteractModels.json中定义
        private Dictionary<string, string> __interactModel = new Dictionary<string, string>();

        // 记录interact各属性的值，类型由__interactModel中定义
        private Dictionary<string, object> __interactData = new Dictionary<string, object>();

        /// <summary>
        /// 构造方法：根据输入的字典interactDict，转换属性值类型后，初始化interact
        /// </summary>
        /// <param name="allInteractModels">从文件InteractModels.json中读取的interact模型</param>
        /// <param name="interactDict">字符串式字典</param>
        public Interact(Dictionary<string, Dictionary<string, string>> allInteractModels, Dictionary<string, string> interactDict)
        {
            if (interactDict.ContainsKey("Type"))
            {
                string interactName = interactDict["Type"] + "Interact";
                if (allInteractModels.ContainsKey(interactName))
                {
                    __interactModel = allInteractModels[interactName];
                    foreach (KeyValuePair<string, string> item in interactDict)
                    {
                        if (__interactModel.ContainsKey(item.Key))
                        {
                            string dataType = __interactModel[item.Key];
                            dynamic value = ChangeType.ConvertString(item.Value, dataType);
                            __interactData.Add(item.Key, value);
                        }
                        else
                        {
                            __interactData.Add(item.Key, item.Value);
                            Trace.TraceWarning($"{item.Key}的属性不在interact模型中。");
                        }
                    }
                }
                else
                {
                    Trace.TraceError($"InteractModels中没有{interactName}的interact模型");
                    throw new Exception($"InteractModels中没有{interactName}的interact模型");
                }
            }
            else
            {
                Trace.TraceError("输入的interact有误，没有Type数据");
                throw new Exception("输入的interact有误，没有Type数据");
            }
        }

        /// <summary>
        /// 构造方法：输入类型良好的字典interactDict，初始化interact
        /// </summary>
        /// <param name="allInteractModels">从文件InteractModels.json中读取的interact模型</param>
        /// <param name="interactDict">类型良好的interact字典</param>
        public Interact(Dictionary<string, Dictionary<string, string>> allInteractModels, Dictionary<string, object> interactDict)
        {
            if (interactDict.ContainsKey("Type"))
            {
                string interactName = interactDict["Type"] + "Interact";
                if (allInteractModels.ContainsKey(interactName))
                {
                    __interactModel = allInteractModels[interactName];
                    __interactData = interactDict;
                }
                else
                {
                    Trace.TraceError($"InteractModels中没有{interactName}的interact模型");
                    throw new Exception($"InteractModels中没有{interactName}的interact模型");
                }
            }
            else
            {
                Trace.TraceError("输入的interact有误，没有Type数据");
                throw new Exception("输入的interact有误，没有Type数据");
            }
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (__interactData.ContainsKey(binder.Name))
            {
                result = __interactData[binder.Name];
                return true;
            }
            else
            {
                result = null;
                Trace.TraceWarning($"当前interact中没有属性{binder.Name}");
                return false;
            }
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            string property = binder.Name;
            if (Array.IndexOf(new string[] { "ObjID", "Type" }, property) != -1) // 输入的property是"ObjID"或"Type"，不可更改。
            {
                Trace.TraceWarning($"interact的属性{property}不可更改");
                return true;
            }
            if (__interactModel.ContainsKey(property))
            {
                string typeString = __interactModel[property];
                if (value.GetType() != Type.GetType(ChangeType.ToFullName(typeString))) // 判断value的类型与属性类型是否相符
                {
                    Trace.TraceWarning($"输入{value}的类型与interact的属性{property}类型不匹配，属性值修改不成功");
                    return true;
                }
                __interactData[property] = value;
                return true;
            }
            else
            {
                Trace.TraceWarning($"当前interact中没有属性{property}");
                return false;
            }
        }
    }
}
